package unitils;

import controller.Service;
import javafx.application.Platform;
import javafx.scene.control.TextArea;
import javafx.scene.image.ImageView;


public class Philosopher implements Runnable{
//    哲学家的状态 0思考 1什么没拿吃饭  2已经拿到左边筷子吃饭  3已经拿到右边筷子吃饭 4什么没拿等待 5拿到左边筷子等待 6拿到右边筷子等待
    private int state;
//    哲学家左边筷子的对象
    private Chopsticks left;
//    哲学家右边筷子的对象
    private Chopsticks right;
//    哲学家的图片id
    private ImageView imageView;
//    哲学家的名字
    private int id;
//    分配筷子的方法（0不操作，1一次分配所有筷子，2最多允许4个同时拿左边筷子，3奇数拿左边，偶数拿右边）
    private int method=0;
//    该模拟是否结束
    private boolean isExit=true;
//    打印输出内容
    private TextArea textArea;
    private Service service;

    public Philosopher(Chopsticks left, Chopsticks right, ImageView imageView, int id,int method,TextArea textArea,Service service) {
        this.left = left;
        this.right = right;
        this.imageView = imageView;
        this.id=id;
        this.method=method;
        this.textArea=textArea;
        this.service=service;
    }

//    不做任何处理的哲学家进餐
    private synchronized void eat1() throws InterruptedException {
//        什么没拿吃饭
        if(this.state==1) {
            if (this.left.takeUp(this)) {
                if (this.right.takeUp(this)) {
                    this.state = 0;
                    Platform.runLater(() -> {
                        this.textArea.appendText(this.getName() + " 正在吃饭... \n");
                        this.imageView.setImage(Service.eatingImage);
                    });
                    Thread.sleep(2000);
                    this.right.putDown(this);
                    this.left.putDown(this);
                } else {
//                 拿到左边筷子等待
                    this.state = 5;
                    this.waiting();
                }
            } else {
//                什么没拿等待
                this.state = 4;
                this.waiting();
            }
//            拿到左边筷子吃饭
        }else if(this.state==2){
            if (this.right.takeUp(this)) {
                this.state = 0;
                Platform.runLater(() -> {
                    this.textArea.appendText(this.getName() + " 正在吃饭... \n");
                    this.imageView.setImage(Service.eatingImage);
                });
                Thread.sleep(2000);
                this.right.putDown(this);
                this.left.putDown(this);
            } else {
//                 拿到左边筷子等待
                this.state = 5;
                this.waiting();
            }
        }
    }

//    一次分配所有筷子
    private synchronized void eat2() throws InterruptedException {
//        什么没拿吃饭
        if(this.state==1) {
            if (this.left.takeUp(this)) {
                if (this.right.takeUp(this)) {
                    this.state = 0;
                    Platform.runLater(() -> {
                        this.textArea.appendText(this.getName() + " 正在吃饭... \n");
                        this.imageView.setImage(Service.eatingImage);
                    });
                    Thread.sleep(2000);
                    this.right.putDown(this);
                    this.left.putDown(this);
                } else {
                    this.left.putDown(this);
//                    什么没拿等待
                    this.state = 4;
                    this.waiting();
                }
            } else {
//                  什么没拿等待
                this.state = 4;
                this.waiting();
            }
        }
    }

//    最多允许4个同时拿左边筷子
    private synchronized void eat3() throws InterruptedException {
//        什么没拿吃饭
        if(this.state==1){
                if (service.addLeftNum()&&this.left.takeUp(this)) {
                    if (this.right.takeUp(this)) {
                        this.state = 0;
                        Platform.runLater(() -> {
                            this.textArea.appendText(this.getName() + " 正在吃饭... \n");
                            this.imageView.setImage(Service.eatingImage);
                        });
                        Thread.sleep(2000);
                        this.right.putDown(this);
                        this.service.lessLeftNum();
                        this.left.putDown(this);
                    } else {
//                        拿到左边筷子等待
                        this.state = 5;
                        this.waiting();
                    }
                } else {
//                    什么没拿等待
                    this.state = 4;
                    this.waiting();
                }
//                拿到左边筷子吃饭
             }else if(this.state==2){
            if (this.right.takeUp(this)) {
                this.state = 0;
                Platform.runLater(() -> {
                    this.textArea.appendText(this.getName() + " 正在吃饭... \n");
                    this.imageView.setImage(Service.eatingImage);
                });
                Thread.sleep(2000);
                this.right.putDown(this);
                this.service.lessLeftNum();
                this.left.putDown(this);
            } else {
//                拿到左边筷子等待
                this.state = 5;
                this.waiting();
            }
          }
        }

//    奇数拿左边，偶数拿右边
    private void eat4() throws InterruptedException {
//        什么没拿吃饭
        if(this.state==1){
            if(this.id%2==1){
//                奇数先拿左边
                if (this.left.takeUp(this)) {
                    if (this.right.takeUp(this)) {
                        this.state = 0;
                        Platform.runLater(() -> {
                            this.textArea.appendText(this.getName() + " 正在吃饭... \n");
                            this.imageView.setImage(Service.eatingImage);
                        });
                        Thread.sleep(2000);
                        this.right.putDown(this);
                        this.left.putDown(this);
                    } else {
//                        拿到左边筷子等待
                        this.state = 5;
                        this.waiting();
                    }
                } else {
//                    什么没拿等待
                    this.state = 4;
                    this.waiting();
                }
//                偶数先拿右边
            }else if(this.id%2==0){
                if (this.right.takeUp(this)) {
                    if (this.left.takeUp(this)) {
                        this.state = 0;
                        Platform.runLater(() -> {
                            this.textArea.appendText(this.getName() + " 正在吃饭... \n");
                            this.imageView.setImage(Service.eatingImage);
                        });
                        Thread.sleep(2000);
                        this.left.putDown(this);
                        this.right.putDown(this);
                    } else {
//                        拿到右边筷子等待
                        this.state = 6;
                        this.waiting();
                    }
                } else {
//                    什么没拿等待
                    this.state = 4;
                    this.waiting();
                }
            }

//                拿到左边筷子吃饭
        }else if(this.state==2){
            if (this.right.takeUp(this)) {
                this.state = 0;
                Platform.runLater(() -> {
                    this.textArea.appendText(this.getName() + " 正在吃饭... \n");
                    this.imageView.setImage(Service.eatingImage);
                });
                Thread.sleep(2000);
                this.right.putDown(this);
                this.service.lessLeftNum();
                this.left.putDown(this);
            } else {
//                拿到左边筷子等待
                this.state = 5;
                this.waiting();
            }

//                拿到右边筷子吃饭
        }else if(this.state==3){
            if (this.left.takeUp(this)) {
                this.state = 0;
                Platform.runLater(() -> {
                    this.textArea.appendText(this.getName() + " 正在吃饭... \n");
                    this.imageView.setImage(Service.eatingImage);
                });
                Thread.sleep(2000);
                this.right.putDown(this);
                this.service.lessLeftNum();
                this.left.putDown(this);
            } else {
//                拿到右边筷子等待
                this.state = 6;
                this.waiting();
            }
        }
    }

//    等待
    private synchronized void waiting() throws InterruptedException {
//        什么没拿等待
         if (this.state == 4) {
          Platform.runLater(() -> {
              this.textArea.appendText(this.getName() + " 手上没有筷子，正在等待筷子... \n");
              this.imageView.setImage(Service.waitingImage);
           });
//          什么没拿吃饭
          this.state=1;
          Thread.sleep(1500);
//          拿到左边筷子等待
       }else if(this.state==5){
             Platform.runLater(() -> {
                 this.textArea.appendText(this.getName() + " 拿到了左边筷子，正在等待右边筷子_"+this.right.getId()+"...\n");
                 this.imageView.setImage(Service.waitingImage);
             });
//          拿到左边筷子吃饭
             this.state=2;
             Thread.sleep(1500);
//             拿到右边筷子等待
         }else if(this.state==6){
             Platform.runLater(() -> {
                 this.textArea.appendText(this.getName() + " 拿到了右边筷子，正在等待左边筷子_"+this.right.getId()+"...\n");
                 this.imageView.setImage(Service.waitingImage);
             });
//          拿到右边筷子吃饭
             this.state=3;
             Thread.sleep(1500);
         }
    }

//    思考
    private synchronized void think() throws InterruptedException {
        if(this.state==0){
            Platform.runLater(() -> {
                this.textArea.appendText(this.getName() + " 正在思考... \n");
                this.imageView.setImage(Service.thinkingImage);
            });
            this.state=1;
            Thread.sleep(1500);
        }

    }

//    多线程
    public void run()  {
        while(!this.isExit){
            try {
                this.think();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
//            吃饭的方法
            switch (this.method){
                case 0:
                    try {
                        eat1();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    break;
                case 1:
                    try {
                        eat2();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    break;
                case 2:
                    try {
                        eat3();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    break;
                case 3:
                    try {
                        eat4();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    break;
                default: System.out.println("出错了");
            }
        }

        Platform.runLater(() -> {
            this.textArea.appendText(this.getName() + " stop \n");
            this.imageView.setImage(Service.initImage);
        });
      }

    public String getName() {
        return "哲学家_"+id;
    }

    public TextArea getTextArea() {
        return textArea;
    }

    public void setExit(boolean exit) {
        isExit = exit;
    }

    public int getId() {
        return id;
    }
}
